package com.xhwl.data.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhwl.common.dto.cent.sdata.*;
import com.xhwl.common.dto.cent.sdata.space.*;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.RoomOrientationEnum;
import com.xhwl.common.enums.RoomTypeEnum;
import com.xhwl.common.enums.config.IndustryEnum;
import com.xhwl.common.enums.space.BuildingTypeEnum;
import com.xhwl.common.enums.space.PublicAreaTypeEnum;
import com.xhwl.common.enums.space.RoomStatusEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.space.AbstractSpaceExcel;
import com.xhwl.common.query.cent.sdata.OrganizationQuery;
import com.xhwl.data.dao.IOrganizationDao;
import com.xhwl.data.dao.IRegionDao;
import com.xhwl.data.pojo.space.RoomCheck;
import com.xhwl.data.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 16:06 2021/10/15
 */
@Service
public class SpaceExcelImportServiceImpl implements ISpaceExcelImportService {

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IFloorService floorService;

    @Autowired
    private IBuildingService buildingService;

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IPublicAreaService publicAreaService;

    @Autowired
    private IOrganizationDao organizationDao;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IRegionDao regionDao;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private ISpaceService spaceService;

    @Autowired
    private IBlockService blockService;

    @Autowired
    private ISpaceFunctionTypeService spaceFunctionTypeService;

    private static final Logger log = LoggerFactory.getLogger(SpaceExcelImportServiceImpl.class);

    private static Random random = new Random();

    @Override
    @Transactional
    public ResultJson batchImportRoom(List<RoomExcelDTO> excelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(excelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<RoomExcelDTO>> errorSpaceList = new ArrayList<>();

        List<RoomExcelDTO> errorList = new ArrayList<>();
        for (RoomExcelDTO excelDTO : excelDTOS) {
            if (StringUtils.isEmpty(excelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            List<RoomTypeEnum> roomTypeEnums = RoomTypeEnum.valuesOf(IndustryEnum.valueOfId((short) 2));
            if (null != excelDTO.getType() && !roomTypeEnums.contains(RoomTypeEnum.valuesOfId(excelDTO.getType()))) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("类型错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            // 状态判断
            List<RoomStatusEnum> roomStatusEnums = RoomStatusEnum.valuesOf(IndustryEnum.valueOfId((short) 2));
            if (roomStatusEnums.isEmpty() && null != excelDTO.getStatus()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("状态错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (!roomStatusEnums.isEmpty() && null != excelDTO.getStatus() && !roomStatusEnums.contains(RoomStatusEnum.valuesOfId(excelDTO.getStatus()))) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("状态错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
        }
        excelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(excelDTOS)) {
            log.info("房间批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }
        Map<String, Integer> chainCodeMap = chainGetParentIdMap(excelDTOS, errorSpaceList, errorList, projectId);

        // 数据处理 1 分组 2 校验
        Set<String> collect = excelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<RoomExcelDTO>> parentAndChildMap = new HashMap<>();

        for (String i : collect) {
            parentAndChildMap.put(i, excelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<RoomExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<RoomExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<RoomExcelDTO> roomExcelDTOS = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList,OrganizationTypeEnum.ROOM.id.intValue(),codeSet);
            correctList.addAll(roomExcelDTOS);
        }

        List<RoomDTO> roomDTOS = new ArrayList<>(excelDTOS.size());
        List<SpaceFunctionType> spaceFunctionTypes = listFunctionType(OrganizationTypeEnum.ROOM);
        for (RoomExcelDTO excelDTO : correctList) {
            RoomDTO roomDTO = new RoomDTO();
            BeanUtils.copyProperties(excelDTO, roomDTO);
            if(null != excelDTO.getType()){
                roomDTO.setFunctionType(excelDTO.getType().intValue());
            }
            roomDTO.setParentId(chainCodeMap.get(excelDTO.getParentChainCode()));
            //填充功能名称
            if (null != excelDTO.getType()) {
                for (SpaceFunctionType spaceFunctionType : spaceFunctionTypes) {
                    if (spaceFunctionType.getId().equals(Integer.valueOf(excelDTO.getType()))) {
                        roomDTO.setFunctionName(spaceFunctionType.getName());
                        break;
                    }
                }
            }
            if (null != excelDTO.getStatus()) {
                roomDTO.setStatus(RoomStatusEnum.valuesOfId(excelDTO.getStatus()));
            }
            try {
                if (null != excelDTO.getExpand()){
                    JSONObject jsonObject = JSONObject.parseObject(excelDTO.getExpand());
                    if (jsonObject.containsKey("orientation") && StringUtils.isNotEmpty(jsonObject.getString("orientation"))) {

                        RoomOrientationEnum r = RoomOrientationEnum.valueOf(jsonObject.getString("orientation").toUpperCase());
                        roomDTO.setOrientation(r);
                    }
                }
            }catch (Exception e){
                log.info("房间朝向错误");
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("房间朝向错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            ResultJson check = RoomCheck.check(roomDTO);
            if(!check.getState()){
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason(check.getMessage());
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            roomDTOS.add(roomDTO);
        }
        roomService.batchCreateFaster(roomDTOS);
        return ResultJson.success(errorSpaceList);
    }

    /**
     * 获取并设置上级信息
     * @param excelDTOS
     * @param chainCode
     * @param chainCodeMap
     * @param errorSpaceList
     * @param errorList
     */
    private <T extends AbstractSpaceExcel> void getUpInfo(List<T> excelDTOS, String chainCode, Map<String, Integer> chainCodeMap, List<ErrorSpace<T>> errorSpaceList, List<T> errorList, Integer projectId){
        String[] split = chainCode.split("-");
        if (1 == split.length) {
            // 这个时候传入的为项目编码
            getProjectAndSetUpInfo(split, excelDTOS, chainCode, chainCodeMap, errorSpaceList, errorList);
        } else {
            getMultiLevelUpInfo(excelDTOS, chainCode, chainCodeMap, errorSpaceList, errorList, projectId);
        }
    }

    /**
     * 根据多个上级获取上级信息
     * @param excelDTOS
     * @param chainCode
     * @param chainCodeMap
     * @param errorSpaceList
     * @param errorList
     */
    private <T extends AbstractSpaceExcel> void getMultiLevelUpInfo(List<T> excelDTOS, String chainCode, Map<String, Integer> chainCodeMap, List<ErrorSpace<T>> errorSpaceList, List<T> errorList, Integer projectId){
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withChainCode(chainCode);
        organizationQuery.setProjectId(projectId);
        Organization organization = organizationService.find(organizationQuery);
        if (null == organization) {
            List<T> noParent = excelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
            for (T t : noParent) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(t);
                errorSpaceList.add(errorSpace);
                errorList.add(t);
            }
            excelDTOS.removeAll(noParent);
        } else {
            chainCodeMap.put(chainCode, organization.getId());
        }
    }

    /**
     * 获取项目信息并设置上级信息
     * @param split
     * @param excelDTOS
     * @param chainCode
     * @param chainCodeMap
     * @param errorSpaceList
     * @param errorList
     */
    private <T extends AbstractSpaceExcel> void getProjectAndSetUpInfo(String[] split, List<T> excelDTOS, String chainCode, Map<String, Integer> chainCodeMap, List<ErrorSpace<T>> errorSpaceList, List<T> errorList){
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("code", split[0]);
        organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
        Organization one = organizationService.getOne(organizationQueryWrapper);
        if (null == one) {
            List<T> noParent = excelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
            for (T t : noParent) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(t);
                errorSpaceList.add(errorSpace);
                errorList.add(t);
            }
            excelDTOS.removeAll(noParent);
        } else {
            chainCodeMap.put(chainCode, one.getId());
        }
    }

    /**
     * 名称编码 重复校验 统一项目下唯一
     */
    private <T extends AbstractSpaceExcel> List<T> baseInfoCheck(Integer projectId, Integer parentId, List<T> lists, List<ErrorSpace<T>> errorSpaceList, int type, List<String> codeSet){
        //编码在项目下唯一
        QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
        organizationQueryWrapper1.select("id", "code");
        organizationQueryWrapper1.eq("project_id", projectId);
        organizationQueryWrapper1.eq("is_deleted", false);
        List<Organization> list = organizationService.list(organizationQueryWrapper1);
        List<String> codeDB = list.stream().filter(j -> StringUtils.isNotEmpty(j.getCode())).map(i -> i.getCode()).collect(Collectors.toList());
        //名称在父级下唯一
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("name");
        organizationQueryWrapper.eq("parent_id", parentId);
        organizationQueryWrapper.eq("is_deleted",false);
        List<Organization> roomOrg = organizationDao.selectList(organizationQueryWrapper);
        List<String> nameDB = roomOrg.stream().map(i -> i.getName()).collect(Collectors.toList());
        //排序在父级下、同类排
        QueryWrapper<Organization> organizationQueryWrapper2 = new QueryWrapper<>();
        organizationQueryWrapper2.select("sort_field");
        organizationQueryWrapper2.eq("parent_id", parentId);
        organizationQueryWrapper2.eq("type",type);
        organizationQueryWrapper2.eq("is_deleted",false);
        List<Organization> sortFieldOrg = organizationDao.selectList(organizationQueryWrapper2);

        Set<String> nameSet = new HashSet<>();
//        Set<String> codeSet = new HashSet<>();
        List<T> correctList = new ArrayList<>();
        int max = 0;
        if (CollectionUtils.isNotEmpty(sortFieldOrg)){
            //max = roomOrg.stream().mapToInt(Organization::getSortField).max().getAsInt();
            //当SortField为空时，会出现空指针异常，使用下面的代码代替
            max = sortFieldOrg.stream()
                    .map(Organization::getSortField)
                    .filter(Objects::nonNull)
                    .mapToInt(Integer::intValue)
                    .max()
                    .orElse(0);
        }
        int i = 1;
        for (T t : lists) {

            t.setSortField(max+i);
            if (nameDB.contains(t.getName()) || nameSet.contains(t.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称重复");
                errorSpace.setObj(t);
                errorSpaceList.add(errorSpace);
                continue;
            }
            if(isCodeRepeated(codeDB, codeSet, t)){
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("编码重复");
                errorSpace.setObj(t);
                errorSpaceList.add(errorSpace);
                continue;
            }
            nameSet.add(t.getName());
            codeSet.add(t.getCode());
            correctList.add(t);
            i++;
        }
        return correctList;
    }

    private static <T extends AbstractSpaceExcel> boolean isCodeRepeated(List<String> codeDB, List<String> codeSet, T t){
        return StringUtils.isNotEmpty(t.getCode()) && (codeDB.contains(t.getCode()) || codeSet.contains(t.getCode()));
    }

    @Override
    @Transactional
    public ResultJson batchImportFloor(List<FloorExcelDTO> excelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(excelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<FloorExcelDTO>> errorSpaceList = new ArrayList<>();

        List<FloorExcelDTO> errorList = new ArrayList<>();
        for (FloorExcelDTO floorExcelDTO : excelDTOS) {
            if (StringUtils.isEmpty(floorExcelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(floorExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(floorExcelDTO);
                continue;
            }
            if (StringUtils.isEmpty(floorExcelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(floorExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(floorExcelDTO);
                continue;
            } else if (50 < floorExcelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(floorExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(floorExcelDTO);
                continue;
            }
        }
        excelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(excelDTOS)) {
            log.info("楼层批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }
        Map<String, Integer> chainCodeMap = chainGetParentIdMap(excelDTOS, errorSpaceList, errorList, projectId);

        // 数据处理 1 分组 2 校验
        Set<String> collect = excelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<FloorExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, excelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<FloorExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<FloorExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<FloorExcelDTO> floorExcelDTOS = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList,OrganizationTypeEnum.FLOOR.id.intValue(),codeSet);
            correctList.addAll(floorExcelDTOS);
        }

        List<FloorDTO> floorDTOS = new ArrayList<>(excelDTOS.size());
        List<SpaceFunctionType> spaceFunctionTypes = listFunctionType(OrganizationTypeEnum.FLOOR);
        for (FloorExcelDTO floorDTO : correctList) {
            FloorDTO floorDTO1 = new FloorDTO();
            BeanUtils.copyProperties(floorDTO, floorDTO1);
            floorDTO1.setParentId(chainCodeMap.get(floorDTO.getParentChainCode()));
            //填充功能名称
            if (null != floorDTO.getType()) {
                for (SpaceFunctionType spaceFunctionType : spaceFunctionTypes) {
                    if (spaceFunctionType.getId().equals(Integer.valueOf(floorDTO.getType()))) {
                        floorDTO1.setFunctionName(spaceFunctionType.getName());
                        break;
                    }
                }
            }
            floorDTOS.add(floorDTO1);
        }
        ResultJson<List> resultJson = floorService.batchCreateFaster(floorDTOS);
        // 是否包含错误数据
        if (null != resultJson.getResult()) {
            errorSpaceList.addAll(resultJson.getResult());
        }
        return ResultJson.success(errorSpaceList);
    }

    @Override
    @Transactional
    public ResultJson batchImportBuilding(List<BuildingExcelDTO> excelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(excelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<BuildingExcelDTO>> errorSpaceList = new ArrayList<>();

        List<BuildingExcelDTO> errorList = new ArrayList<>();
        for (BuildingExcelDTO excelDTO : excelDTOS) {
            if (StringUtils.isEmpty(excelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (StringUtils.isEmpty(excelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            } else if (50 < excelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            List<BuildingTypeEnum> buildingTypeEnums = BuildingTypeEnum.valuesOf(IndustryEnum.valueOfId((short) 2));
            if (null != excelDTO.getType() && !buildingTypeEnums.contains(BuildingTypeEnum.valueOf(excelDTO.getType().shortValue()))) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("类型错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
        }
        excelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(excelDTOS)) {
            log.info("楼栋批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }
        Map<String, Integer> chainCodeMap = chainGetParentIdMap(excelDTOS, errorSpaceList, errorList, projectId);

        // 数据处理 1 分组 2 校验
        Set<String> collect = excelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<BuildingExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, excelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<BuildingExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<BuildingExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<BuildingExcelDTO> buildingExcelDTOS = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList, OrganizationTypeEnum.BUILDING.id.intValue(),codeSet);
            correctList.addAll(buildingExcelDTOS);
        }

        List<BuildingDTO> buildingDTOS = new ArrayList<>(excelDTOS.size());
        List<SpaceFunctionType> spaceFunctionTypes = listFunctionType(OrganizationTypeEnum.BUILDING);
        for (BuildingExcelDTO buildingExcelDTO : correctList) {
            BuildingDTO buildingDTO = new BuildingDTO();
            BeanUtils.copyProperties(buildingExcelDTO, buildingDTO);
            buildingDTO.setParentId(chainCodeMap.get(buildingExcelDTO.getParentChainCode()));
            //填充功能名称
            if (null != buildingExcelDTO.getType()) {
                for (SpaceFunctionType spaceFunctionType : spaceFunctionTypes) {
                    if (spaceFunctionType.getId().equals(Integer.valueOf(buildingExcelDTO.getType()))) {
                        buildingDTO.setFunctionName(spaceFunctionType.getName());
                        break;
                    }
                }
            }
            buildingDTOS.add(buildingDTO);
        }
        ResultJson<List> resultJson = buildingService.batchCreateFaster(buildingDTOS);
        // 是否包含错误数据
        if (null != resultJson.getResult()) {
            errorSpaceList.addAll(resultJson.getResult());
        }
        return ResultJson.success(errorSpaceList);
    }

    @Override
    @Transactional
    public ResultJson batchImportArea(List<AreaExcelDTO> excelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(excelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<AreaExcelDTO>> errorSpaceList = new ArrayList<>();

        List<AreaExcelDTO> errorList = new ArrayList<>();

        Set<String> address = new HashSet<>();
        for (AreaExcelDTO excelDTO : excelDTOS) {
            if (StringUtils.isEmpty(excelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (StringUtils.isEmpty(excelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            } else if (50 < excelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (StringUtils.isNotEmpty(excelDTO.getRegion()) && 50 < excelDTO.getRegion().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("详细地址过长");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
        }
        excelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(excelDTOS)) {
            log.info("楼栋批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }

        // 上级信息
        Map<String, Integer> chainCodeMap = chainGetParentIdMap(excelDTOS, errorSpaceList, errorList, projectId);

        // 地址信息解析
        Map<String, String> regionMap = new HashMap<>();
        Map<String, Region> regionDBMap = new HashMap<>();
        for (AreaExcelDTO excelDTO : excelDTOS) {
            if (StringUtils.isNotEmpty(excelDTO.getRegion())) {

                String[] split = excelDTO.getRegion().split("-");
                StringBuilder merName = new StringBuilder("中国");
                for (String s : split) {
                    merName.append(",").append(s);
                }
                regionMap.put(excelDTO.getRegion(), merName.toString());
                address.add(merName.toString());
            }
        }
        if (CollectionUtils.isNotEmpty(address)) {
            log.info("开始查询地址信息 {}", JSONObject.toJSONString(address));
            QueryWrapper<Region> regionQueryWrapper = new QueryWrapper<>();
            regionQueryWrapper.select("id", "pid", "mer_name", "level");
            regionQueryWrapper.in("mer_name", address);
            List<Region> regions = regionDao.selectList(regionQueryWrapper);
            if (!regions.isEmpty()) {
                regionDBMap = regions.stream().collect(Collectors.toMap(Region::getMerName, Function.identity()));
                List<Region> all = regionService.all(null);
                Map<Integer, Region> allMap = all.stream().collect(Collectors.toMap(Region::getId, Function.identity()));
                for (AreaExcelDTO excelDTO : excelDTOS) {
                    if (StringUtils.isNotEmpty(excelDTO.getRegion())) {
                        String merName = regionMap.get(excelDTO.getRegion());
                        Region district = regionDBMap.get(merName);
                        if (null != district && district.getLevel() == 3) {
                            excelDTO.setDistrictId(district.getId());
                            // 查询省市信息 固定三级
                            Region city = allMap.get(district.getPid());
                            if (null != city && city.getLevel() != 1) {
                                excelDTO.setCityId(city.getId());
                                Region province = allMap.get(city.getPid());
                                if (null != province) {
                                    excelDTO.setProvinceId(province.getId());
                                }
                            }
                        }
                    }
                }
            }
        }

        Set<String> collect = excelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<AreaExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, excelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<AreaExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<AreaExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<AreaExcelDTO> areaExcelDTOS = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList, OrganizationTypeEnum.AREA.id.intValue(), codeSet);
            correctList.addAll(areaExcelDTOS);
        }

        List<AreaDTO> areaDTOS = new ArrayList<>(excelDTOS.size());
        for (AreaExcelDTO areaExcelDTO : correctList) {
            nameChangeId(areaExcelDTO,errorSpaceList);
            AreaDTO areaDTO = new AreaDTO();
            BeanUtils.copyProperties(areaExcelDTO, areaDTO);
            areaDTO.setParentId(chainCodeMap.get(areaExcelDTO.getParentChainCode()));
            if (null != areaDTO.getExpand()){
                JSONObject jsonObject = JSONObject.parseObject(areaExcelDTO.getExpand());
                if (jsonObject.containsKey("latitude")
                        && StringUtils.isNotEmpty(jsonObject.getString("latitude"))
                        && !jsonObject.getString("latitude").equals("")){
                    areaDTO.setLatitude(jsonObject.getString("latitude"));
                }
                if (jsonObject.containsKey("longitude")
                        && StringUtils.isNotEmpty(jsonObject.getString("longitude"))
                        && !jsonObject.getString("longitude").equals("")){
                    areaDTO.setLatitude(jsonObject.getString("longitude"));
                }
            }
            areaDTOS.add(areaDTO);
        }
        ResultJson<List> resultJson = areaService.batchCreateFaster(areaDTOS);
        log.warn("导入区域 ： {}", JSONObject.toJSONString(resultJson.getResult()));
        // 是否包含错误数据
        if (null != resultJson.getResult()) {
            errorSpaceList.addAll(resultJson.getResult());
        }
        return ResultJson.success(errorSpaceList);
    }

    private static final String PROJECT_KEY = "PROJECT_ID";

    /**
     * 获取上级信息， 错误的放入错误集合中
     *
     * @param excelDTOS
     * @param errorSpaceList
     * @param errorList
     * @return key excel中导入的上级空间编码, value 上级空间对应的结点id
     */
    private <T extends AbstractSpaceExcel> Map<String, Integer> chainGetParentIdMap(List<T> excelDTOS, List<ErrorSpace<T>> errorSpaceList, List<T> errorList, Integer projectId) {
        Map<String, Integer> chainCodeMap = new HashMap<>();
        List<String> chainCodes = excelDTOS.stream().map(i -> i.getParentChainCode()).distinct().collect(Collectors.toList());
        for (String chainCode : chainCodes) {
            getUpInfo(excelDTOS, chainCode, chainCodeMap, errorSpaceList, errorList, projectId);
        }
        return chainCodeMap;
    }

    /**
     * 上级信息检查
     * @param excelDTOS
     * @param errorSpaceList
     * @param errorList
     * @param chainCodeMap
     * @param chainCode
     * @param organization
     */
    private <T extends AbstractSpaceExcel> void upInfoCheck(List<T> excelDTOS, List<ErrorSpace<T>> errorSpaceList, List<T> errorList, Map<String, Integer> chainCodeMap, String chainCode, Organization organization) {
        if (null == organization) {
            List<T> noParent = excelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
            for (T t : noParent) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(t);
                errorSpaceList.add(errorSpace);
                errorList.add(t);
            }
            excelDTOS.removeAll(noParent);
        } else {
            chainCodeMap.put(PROJECT_KEY, organization.getProjectId());
            chainCodeMap.put(chainCode, organization.getId());
        }
    }

    /**
     * 获取上级信息， 错误的放入错误集合中
     *
     * @param excelDTOS
     * @param chainCodes
     * @param errorSpaceList
     * @param errorList
     * @return key excel中导入的上级空间编码, value 上级空间对应的结点id
     */
    private Map<String, Integer> chainGetParentIdMap2(List<BlockExcelDTO> excelDTOS, List<String> chainCodes, List<ErrorSpace> errorSpaceList, List<BlockExcelDTO> errorList) {
        Map<String, Integer> chainCodeMap = new HashMap<>();
        for (String chainCode : chainCodes) {
            String[] split = chainCode.split("-");
            if (1 == split.length) {
                // 这个时候传入的为项目编码
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("code", split[0]);
                organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
                Organization one = organizationService.getOne(organizationQueryWrapper);
                if (null == one) {
                    List<BlockExcelDTO> noParent = excelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (BlockExcelDTO areaExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(areaExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(areaExcelDTO);
                    }
                    excelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, one.getId());
                }
            } else {
                // 传入了二级以上的编码
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.withChainCode(chainCode);
                Organization organization = organizationService.find(organizationQuery);
                if (null == organization) {
                    List<BlockExcelDTO> noParent = excelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (BlockExcelDTO areaExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(areaExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(areaExcelDTO);
                    }
                    excelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, organization.getId());
                }
            }
        }
        return chainCodeMap;
    }

    @Override
    @Transactional
    public ResultJson batchImportPublicArea(List<PublicAreaExcelDTO> excelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(excelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<PublicAreaExcelDTO>> errorSpaceList = new ArrayList<>();

        List<PublicAreaExcelDTO> errorList = new ArrayList<>();
        for (PublicAreaExcelDTO excelDTO : excelDTOS) {
            if (StringUtils.isEmpty(excelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (StringUtils.isEmpty(excelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            } else if (50 < excelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            List<PublicAreaTypeEnum> publicAreaTypeEnums = PublicAreaTypeEnum.valuesOf(IndustryEnum.valueOfId((short) 2));
            if (null != excelDTO.getType() && !publicAreaTypeEnums.contains(PublicAreaTypeEnum.valueOf(excelDTO.getType().shortValue()))) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("类型错误");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
        }
        excelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(excelDTOS)) {
            log.info("楼栋批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }

        Map<String, Integer> chainCodeMap = chainGetParentIdMap(excelDTOS, errorSpaceList, errorList, projectId);
        // 数据处理 1 分组 2 校验
        Set<String> collect = excelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<PublicAreaExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, excelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<PublicAreaExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<PublicAreaExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<PublicAreaExcelDTO> areaExcelDTOS = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList, OrganizationTypeEnum.PUBLIC_AREA.id.intValue(),codeSet);
            correctList.addAll(areaExcelDTOS);
        }

        List<PublicAreaDTO> areaDTOS = new ArrayList<>(correctList.size());
        List<SpaceFunctionType> spaceFunctionTypes = listFunctionType(OrganizationTypeEnum.PUBLIC_AREA);
        for (PublicAreaExcelDTO areaExcelDTO : correctList) {
            PublicAreaDTO areaDTO = new PublicAreaDTO();
            BeanUtils.copyProperties(areaExcelDTO, areaDTO);
            areaDTO.setParentId(chainCodeMap.get(areaExcelDTO.getParentChainCode()));
            //填充功能名称
            if (null != areaExcelDTO.getType()) {
                for (SpaceFunctionType spaceFunctionType : spaceFunctionTypes) {
                    if (spaceFunctionType.getId().equals(Integer.valueOf(areaExcelDTO.getType()))) {
                        areaDTO.setFunctionName(spaceFunctionType.getName());
                        break;
                    }
                }
            }
            areaDTOS.add(areaDTO);
        }
        publicAreaService.batchCreateFaster(areaDTOS);
        // 是否包含错误数据
        return ResultJson.success(errorSpaceList);
    }

    @Override
    @Transactional
    public ResultJson batchImportSpace(List<JSONObject> spaces, OrganizationType organizationType, Account account, Integer projectId) {

        if (CollectionUtils.isEmpty(spaces)) {
            return ResultJson.fail("空数据");
        }
        String source = organizationType.getSource();
        if (StringUtils.isEmpty(source)) {
            return ResultJson.fail("空间配置错误");
        }
        JSONObject jsonObject = JSONObject.parseObject(source);
        List<String> fields = new ArrayList<>();
        fields.add("parentName");
        fields.add("parentChainCode");
        JSONArray jsonArray = jsonObject.getJSONArray("fields");
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                fields.add(jsonArray.getJSONObject(i).getString("vModel"));
            }
        }

        //获得组织信息
        List<String> chainCodes = new ArrayList<>();
        Map<String,Integer> codeMap = new HashMap<>();
        Map<String,Integer> nameMap = new HashMap<>();
        for(JSONObject space : spaces){
            chainCodes.add((String) space.get("parentChainCode"));
            if(space.get("code") != null){
                if(codeMap.containsKey(space.get("code"))){
                    codeMap.put((String) space.get("code"),codeMap.get(space.get("code"))+1);
                }else {
                    codeMap.put((String) space.get("code"),1);
                }
            }
            if(space.get("name") != null){
                if(nameMap.containsKey(space.get("name"))){
                    nameMap.put((String) space.get("name"),nameMap.get(space.get("name"))+1);
                }else {
                    nameMap.put((String) space.get("name"),1);
                }
            }
        }
        Map<String, Integer> chainCodeMap = new HashMap<>();
        List<Space> importSpace = new ArrayList<>();
        for (String chainCode : chainCodes) {
            String[] split = chainCode.split("-");
            if (1 == split.length) {
                // 这个时候传入的为项目编码
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("code", split[0]);
                organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
                Organization one = organizationService.getOne(organizationQueryWrapper);
                if (null != one)  {
                    chainCodeMap.put(chainCode, one.getId());
                }
            } else {
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.withChainCode(chainCode);
                Organization organization = organizationService.find(organizationQuery);
                if (null != organization) {
                    chainCodeMap.put(chainCode, organization.getId());
                }
            }
        }
        //校验
        List<ErrorSpace> errorList = new ArrayList<>();
        List<JSONObject> errorEntity = new ArrayList<>();

        // 数据处理 1 分组 2 排序
        Set<String> collect = spaces.stream().map(i -> i.getString("parentChainCode")).collect(Collectors.toSet());
        Map<String, List<JSONObject>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, spaces.stream().filter(j -> i.equals(j.getString("parentChainCode"))).collect(Collectors.toList()));
        }
        for (Map.Entry<String, List<JSONObject>> entry : parentAndChildMap.entrySet()) {
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.select("name","sort_field");
            organizationQueryWrapper.eq("parent_id", chainCodeMap.get(entry.getKey()));
            organizationQueryWrapper.eq("type",organizationType.getId());
            organizationQueryWrapper.eq("is_deleted",false);
            List<Organization> roomOrg = organizationDao.selectList(organizationQueryWrapper);

            int max = 0;
            if (CollectionUtils.isNotEmpty(roomOrg)){
                max = roomOrg.stream().mapToInt(Organization::getSortField).max().getAsInt();
            }
            int i = 1;
            for (JSONObject jsonObject1 : entry.getValue()){
                jsonObject1.put("sortField",max+i);
                i++;
            }
        }
        for (JSONObject space : spaces) {
            String name = (String) space.get("name");
            if (StringUtils.isEmpty(name)) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(space);
                errorList.add(errorSpace);
                errorEntity.add(space);
                continue;
            }

            if (name.length() > 30) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称超过长度限制");
                errorSpace.setObj(space);
                errorList.add(errorSpace);
                errorEntity.add(space);
                continue;
            }
            //校验code不重复
            if(space.get("code") != null && space.get("code") !=  ""){
                if(codeMap.get(space.get("code"))>1) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("code重复");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                    continue;
                }
                QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
                organizationQueryWrapper1.select("id");
                organizationQueryWrapper1.eq("code", space.get("code"));
                List<Organization> organizations1 = organizationDao.selectList(organizationQueryWrapper1);
                if(CollectionUtil.isNotEmpty(organizations1)) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("code已存在");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                    continue;
                }
            }
            String parentChainCode = (String) space.get("parentChainCode");
            if (StringUtils.isEmpty(parentChainCode)) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(space);
                errorList.add(errorSpace);
                continue;
            }
            if(chainCodeMap.get(space.get("parentChainCode")) == null){
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(space);
                errorSpace.setObj(errorSpace);
                errorList.add(errorSpace);
                continue;
            }
            QueryWrapper<Organization> organizationQueryName = new QueryWrapper<>();
            organizationQueryName.select("id");
            organizationQueryName.eq("name", space.get("name"));
            organizationQueryName.eq("parent_id",chainCodeMap.get(space.getString("parentChainCode")));
            List<Organization> orgName = organizationDao.selectList(organizationQueryName);
            if(CollectionUtil.isNotEmpty(orgName)) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称已存在");
                errorSpace.setObj(space);
                errorList.add(errorSpace);
                continue;
            }

            boolean flag = false;
            Map<String, Object> spaceMap = new HashMap<>();
            for (Object field : fields) {
                Object value = space.get(field);
               /* if (StringUtils.isNotEmpty(value) && value.length() > 30) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("长度超过限制");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                    flag = true;
                    break;
                } else {*/
                spaceMap.put((String) field, value);
                // }
            }

            if(flag){
                continue;
            }
            Space space1 = new Space();
            space1.setName((String) spaceMap.get("name"));
            space1.setType(organizationType.getId());
            space1.setParentId(chainCodeMap.get(space.get("parentChainCode")));
            space1.setSortField(space.getInteger("sortField"));
            if (StringUtils.isNotEmpty((String) space.get("code"))) {
                space1.setCode((String) space.get("code"));
            } else {
                space1.setCode(UUID.randomUUID().toString().replaceAll("-", ""));
            }
            space1.setData(JSONObject.toJSONString(spaceMap));
            space1.setExpand(JSONObject.toJSONString(spaceMap));
            importSpace.add(space1);
        }
        //这™写的啥垃圾
       /* List<String> chainCodes = spaces.stream().map(i -> (String) i.get("parentChainCode")).distinct().collect(Collectors.toList());
        Map<String, Integer> chainCodeMap = new HashMap<>();
        for (String chainCode : chainCodes) {
            String[] split = chainCode.split("-");
            if (1 == split.length) {
                // 这个时候传入的为项目编码
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("code", split[0]);
                organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
                Organization one = organizationService.getOne(organizationQueryWrapper);
                if (null == one) {
                    List<JSONObject> noParent = spaces.stream().filter(i -> i.get("parentChainCode").equals(chainCode)).collect(Collectors.toList());
                    for (JSONObject space : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(space);
                        errorSpace.setObj(errorSpace);
                        errorList.add(errorSpace);
                    }
                    spaces.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, one.getId());
                }
            } else {
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.withChainCode(chainCode);
                Organization organization = organizationService.find(organizationQuery);
                if (null == organization) {
                    List<JSONObject> noParent = spaces.stream().filter(i -> i.get("parentChainCode").equals(chainCode)).collect(Collectors.toList());
                    for (JSONObject space : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(space);
                        errorList.add(errorSpace);
                    }
                    spaces.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, organization.getId());
                }
            }
        }
        JSONObject jsonObject = JSONObject.parseObject(source);
        List<String> fields = new ArrayList<>();
        fields.add("parentName");
        fields.add("parentChainCode");
        JSONArray jsonArray = jsonObject.getJSONArray("fields");
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                fields.add(jsonArray.getJSONObject(i).getString("vModel"));
            }
        }
        //fields.addAll((List<String>) jsonObject.get("order"));
        List<Space> importSpace = new ArrayList<>();

        for (JSONObject space : spaces) {
            String parentChainCode = (String) space.get("parentChainCode");
            if (StringUtils.isEmpty(parentChainCode)) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("上级信息不存在");
                errorSpace.setObj(space);
                errorList.add(errorSpace);
            }
            Map<String, Object> spaceMap = new HashMap<>();
            for (Object field : fields) {
                String value = (String) space.get(field);
                if (StringUtils.isNotEmpty(value) && value.length() > 30) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("长度超过限制");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                } else {
                    spaceMap.put((String) field, value);
                }
            }

            Space space1 = new Space();
            space1.setName((String) spaceMap.get("name"));
            space1.setType(organizationType.getId());
            space1.setParentId(chainCodeMap.get(space.get("parentChainCode")));
            if (StringUtils.isNotEmpty((String) space.get("code"))) {
                space1.setCode((String) space.get("code"));
            } else {
                space1.setCode(UUID.randomUUID().toString().replaceAll("-", ""));
            }
            space1.setData(JSONObject.toJSONString(spaceMap));

            importSpace.add(space1);
        }*/

       /* // 编码 名称校验
        Map<Integer, List<Space>> spaceMap = new HashMap<>();
        for (Space space : importSpace) {
            spaceMap.put(space.getParentId(), null);
        }

        for (Map.Entry<Integer, List<Space>> spaceEntry : spaceMap.entrySet()) {
            List<Space> collect = importSpace.stream().filter(i -> i.getParentId().equals(spaceEntry.getKey())).collect(Collectors.toList());
            spaceEntry.setValue(collect);
        }

        for (Map.Entry<Integer, List<Space>> spaceEntry : spaceMap.entrySet()) {

            Integer parentId = spaceEntry.getKey();

            Organization parent = organizationDao.selectById(parentId);
            if (null == parent) {
                List<Space> value = spaceEntry.getValue();
                for (Space space : value) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("父级不存在");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                }
            }
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.select("name", "id");
            organizationQueryWrapper.eq("parent_id", parentId);
            List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
            Map<String, Object> repeatMapDB = new HashMap<>();
            if (!organizations.isEmpty()) {
                repeatMapDB = organizations.stream().collect(Collectors.toMap(Organization::getName, Function.identity(),(oldValue,newValue)->newValue));
            }
            Map<String, Space> repeatMap = new HashMap<>();

            for (Space space : importSpace) {
                if (repeatMapDB.containsKey(space.getName()) || repeatMap.containsKey(space.getName())) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("名称重复");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                } else {
                    repeatMap.put(space.getName(), space);
                }
            }

            List<Space> correctList = new ArrayList<>();
            for (Map.Entry<String, Space> entry : repeatMap.entrySet()) {
                correctList.add(entry.getValue());
            }

            // code 校验
            Map<String, Space> codeMap = new HashMap<>();
            Map<String, Object> codeMapDB = new HashMap<>();
            // 这里仅校验同一个项目下的编码重复
            QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
            organizationQueryWrapper1.select("id", "code");
            organizationQueryWrapper1.eq("project_id", parent.getProjectId());
            organizationQueryWrapper1.eq("type", importSpace.get(0).getType());
            organizationQueryWrapper1.isNotNull("code");
            List<Organization> organizations1 = organizationDao.selectList(organizationQueryWrapper1);
            if (!organizations1.isEmpty()) {
                codeMapDB = organizations1.stream().collect(Collectors.toMap(Organization::getCode, Organization::getCode,(oldValue,newValue)->newValue));
            }
            for (Space space : correctList) {
                if (!com.xhwl.common.utils.StringUtils.isEmpty(space.getCode()) && (codeMapDB.containsKey(space.getCode()) || codeMap.containsKey(space.getCode()))) {
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("编码重复");
                    errorSpace.setObj(space);
                    errorList.add(errorSpace);
                } else {
                    codeMap.put(space.getName(), space);
                }
            }
            correctList = correctList.stream().filter(i -> codeMap.containsKey(i.getName())).collect(Collectors.toList());
            if (correctList.isEmpty()) {
                log.info("校验后没有合适的数据");
                return ResultJson.success(errorList);
            }
        }*/

        if (CollectionUtil.isEmpty(importSpace)) {
            log.info("校验后没有合适的数据");
            return ResultJson.success(errorList);
        }
        ResultJson<List> resultJson = spaceService.batchCreateFaster(importSpace, account);
        // 是否包含错误数据
        if (null != resultJson.getResult()) {
            errorList.addAll(resultJson.getResult());
        }
        return ResultJson.success(errorList);
    }

    @Override
    public ResultJson<List<ErrorSpace>> batchImportUnit(List<UnitExcelDTO> unitExcelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(unitExcelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<UnitExcelDTO>> errorSpaceList = new ArrayList<>();

        List<UnitExcelDTO> errorList = new ArrayList<>();
        for (UnitExcelDTO unitExcelDTO : unitExcelDTOS) {
            if (StringUtils.isEmpty(unitExcelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(unitExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(unitExcelDTO);
                continue;
            }
            if (StringUtils.isEmpty(unitExcelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(unitExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(unitExcelDTO);
                continue;
            } else if (50 < unitExcelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(unitExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(unitExcelDTO);
                continue;
            }
        }
        unitExcelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(unitExcelDTOS)) {
            log.info("楼层批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }
        List<String> chainCodes = unitExcelDTOS.stream().map(i -> i.getParentChainCode()).distinct().collect(Collectors.toList());
        Map<String, Organization> chainCodeMap = new HashMap<>();
        for (String chainCode : chainCodes) {
            String[] split = chainCode.split("-");
            if (1 == split.length) {
                // 这个时候传入的为项目编码
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("code", split[0]);
                organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
                Organization one = organizationService.getOne(organizationQueryWrapper);
                if (null == one) {
                    List<UnitExcelDTO> noParent = unitExcelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (UnitExcelDTO unitExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(unitExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(unitExcelDTO);
                    }
                    unitExcelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, one);
                }
            } else {
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.withChainCode(chainCode);
                Organization organization = organizationService.find(organizationQuery);
                if (null == organization) {
                    List<UnitExcelDTO> noParent = unitExcelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (UnitExcelDTO unitExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(unitExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(unitExcelDTO);
                    }
                    unitExcelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, organization);
                }
            }
        }

        // 数据处理 1 分组 2 校验
        Set<String> collect = unitExcelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<UnitExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, unitExcelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<UnitExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<UnitExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<UnitExcelDTO> unitExcelDTOList = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()).getId(), entry.getValue(), errorSpaceList, OrganizationTypeEnum.UNIT.id.intValue(), codeSet);
            correctList.addAll(unitExcelDTOList);
        }
        List<Organization> units = new ArrayList<>(correctList.size());
        for (UnitExcelDTO unitExcelDTO : correctList) {
            Organization organization = new Organization();
            Organization parent = chainCodeMap.get(unitExcelDTO.getParentChainCode());
            organization.setParentId(parent.getId());
            StringBuilder rs = new StringBuilder();
            for (int i = 0; i < 8; i++) {
                rs.append(random.nextInt(10));
            }
            if (null != unitExcelDTO.getCode() && StringUtils.isNotEmpty(unitExcelDTO.getCode())){
                organization.setCode(unitExcelDTO.getCode());
            }else {
                organization.setCode("U" + rs);
            }
            organization.setSortField(unitExcelDTO.getSortField());
            organization.setIndustryId(parent.getIndustryId());
            organization.setEnterpriseId(parent.getEnterpriseId());
            organization.setName(unitExcelDTO.getName());
            organization.setLevel(parent.getLevel() + 1);
            organization.setParentId(parent.getId());
            organization.setIsDeleted(false);
            organization.setType(OrganizationTypeEnum.UNIT.id.intValue());
            organization.setSortField(unitExcelDTO.getSortField());
            organization.setProjectId(parent.getProjectId());
            units.add(organization);
        }
        organizationService.saveBatch(units);
        return ResultJson.success(errorSpaceList);
    }

    @Override
    public ResultJson<List<ErrorSpace>> batchImportBalcony(List<BalconyExcelDTO> balconyExcelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(balconyExcelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<BalconyExcelDTO>> errorSpaceList = new ArrayList<>();

        List<BalconyExcelDTO> errorList = new ArrayList<>();
        for (BalconyExcelDTO balconyExcelDTO : balconyExcelDTOS) {
            if (StringUtils.isEmpty(balconyExcelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(balconyExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(balconyExcelDTO);
                continue;
            }
            if (StringUtils.isEmpty(balconyExcelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(balconyExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(balconyExcelDTO);
                continue;
            } else if (50 < balconyExcelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(balconyExcelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(balconyExcelDTO);
                continue;
            }
        }
        balconyExcelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(balconyExcelDTOS)) {
            log.info("楼层批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }
        List<String> chainCodes = balconyExcelDTOS.stream().map(i -> i.getParentChainCode()).distinct().collect(Collectors.toList());
        Map<String, Organization> chainCodeMap = new HashMap<>();
        for (String chainCode : chainCodes) {
            String[] split = chainCode.split("-");
            if (1 == split.length) {
                // 这个时候传入的为项目编码
                QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                organizationQueryWrapper.eq("code", split[0]);
                organizationQueryWrapper.eq("type", OrganizationTypeEnum.PROJECT.id);
                Organization one = organizationService.getOne(organizationQueryWrapper);
                if (null == one) {
                    List<BalconyExcelDTO> noParent = balconyExcelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (BalconyExcelDTO balconyExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(balconyExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(balconyExcelDTO);
                    }
                    balconyExcelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, one);
                }
            } else {
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.withChainCode(chainCode);
                Organization organization = organizationService.find(organizationQuery);
                if (null == organization) {
                    List<BalconyExcelDTO> noParent = balconyExcelDTOS.stream().filter(i -> i.getParentChainCode().equals(chainCode)).collect(Collectors.toList());
                    for (BalconyExcelDTO balconyExcelDTO : noParent) {
                        ErrorSpace errorSpace = new ErrorSpace();
                        errorSpace.setReason("上级信息不存在");
                        errorSpace.setObj(balconyExcelDTO);
                        errorSpaceList.add(errorSpace);
                        errorList.add(balconyExcelDTO);
                    }
                    balconyExcelDTOS.removeAll(noParent);
                } else {
                    chainCodeMap.put(chainCode, organization);
                }
            }
        }

        // 数据处理 1 分组 2 校验
        Set<String> collect = balconyExcelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<BalconyExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, balconyExcelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<BalconyExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<BalconyExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<BalconyExcelDTO> balconyExcelDTOS1 = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()).getId(), entry.getValue(), errorSpaceList, OrganizationTypeEnum.BALCONY.id.intValue(),codeSet);
            correctList.addAll(balconyExcelDTOS1);
        }
        List<Organization> units = new ArrayList<>(correctList.size());
        for (BalconyExcelDTO balconyExcelDTO : correctList) {
            Organization organization = new Organization();
            Organization parent = chainCodeMap.get(balconyExcelDTO.getParentChainCode());
            organization.setParentId(parent.getId());
            if(StringUtils.isEmpty(balconyExcelDTO.getCode())){
                organization.setCode("BA" + random.nextInt(10));
            }else{
                organization.setCode(balconyExcelDTO.getCode());
            }
            organization.setSortField(balconyExcelDTO.getSortField());
            organization.setIndustryId(parent.getIndustryId());
            organization.setEnterpriseId(parent.getEnterpriseId());
            organization.setName(balconyExcelDTO.getName());
            organization.setLevel(parent.getLevel() + 1);
            organization.setParentId(parent.getId());
            organization.setIsDeleted(false);
            organization.setSortField(balconyExcelDTO.getSortField());
            organization.setType(OrganizationTypeEnum.BALCONY.id.intValue());
            organization.setProjectId(parent.getProjectId());
            units.add(organization);
        }
        organizationService.saveBatch(units);
        return ResultJson.success(errorSpaceList);
    }

    @Override
    public ResultJson<List<ErrorSpace>> batchImportBlock(List<BlockExcelDTO> blockExcelDTOS, Account account, Integer projectId) {
        if (CollectionUtils.isEmpty(blockExcelDTOS)) {
            return ResultJson.fail("空数据");
        }
        List<ErrorSpace<BlockExcelDTO>> errorSpaceList = new ArrayList<>();

        List<BlockExcelDTO> errorList = new ArrayList<>();

        for (BlockExcelDTO excelDTO : blockExcelDTOS) {
            if (StringUtils.isEmpty(excelDTO.getParentChainCode())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少上级信息");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
            if (StringUtils.isEmpty(excelDTO.getName())) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("缺少名称");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            } else if (50 < excelDTO.getName().length()) {
                ErrorSpace errorSpace = new ErrorSpace();
                errorSpace.setReason("名称过长");
                errorSpace.setObj(excelDTO);
                errorSpaceList.add(errorSpace);
                errorList.add(excelDTO);
                continue;
            }
        }
        blockExcelDTOS.removeAll(errorList);
        if (CollectionUtils.isEmpty(blockExcelDTOS)) {
            log.info("楼栋批量导入校验后没有符合的数据");
            return ResultJson.success(errorSpaceList);
        }

        // 上级信息
        Map<String, Integer> chainCodeMap = chainGetParentIdMap(blockExcelDTOS, errorSpaceList, errorList, projectId);

        Set<String> collect = blockExcelDTOS.stream().map(i -> i.getParentChainCode()).collect(Collectors.toSet());
        Map<String, List<BlockExcelDTO>> parentAndChildMap = new HashMap<>();
        for (String i : collect) {
            parentAndChildMap.put(i, blockExcelDTOS.stream().filter(j -> i.equals(j.getParentChainCode())).collect(Collectors.toList()));
        }
        List<BlockExcelDTO> correctList = new ArrayList<>();
        List<String> codeSet = new ArrayList<>();
        for (Map.Entry<String, List<BlockExcelDTO>> entry : parentAndChildMap.entrySet()) {
            List<BlockExcelDTO> blockExcelDTOS1 = baseInfoCheck(projectId, chainCodeMap.get(entry.getKey()), entry.getValue(), errorSpaceList, OrganizationTypeEnum.BLOCK.id.intValue(), codeSet);
            correctList.addAll(blockExcelDTOS1);
        }

        List<Block> blocks = new ArrayList<>(blockExcelDTOS.size());
        for (BlockExcelDTO blockExcelDTO : correctList) {
            Block block = new Block();
            BeanUtils.copyProperties(blockExcelDTO, block);
            block.setParentId(chainCodeMap.get(blockExcelDTO.getParentChainCode()));
            blocks.add(block);
        }
        ResultJson<List> resultJson = blockService.batchCreateFaster(blocks);
        log.warn("导入区域 ： {}", JSONObject.toJSONString(resultJson.getResult()));
        return ResultJson.success(errorSpaceList);
    }

    private List<SpaceFunctionType> listFunctionType(OrganizationTypeEnum organizationTypeEnum) {
        return spaceFunctionTypeService.list(new QueryWrapper<SpaceFunctionType>()
                .eq("org_type", organizationTypeEnum.getId()));
    }

    /**
     * 将区域名专场id
     */
    private void nameChangeId(AreaExcelDTO areaExcelDTO,List<ErrorSpace<AreaExcelDTO>> errorSpaceList){
        if(areaExcelDTO.getRegion() == null || areaExcelDTO.getRegion().equals("")){
            return;
        }
        String[] split = areaExcelDTO.getRegion().split("-");
        if (split.length == 0){
            return;
        }
        QueryWrapper<Region> queryWrapper = new QueryWrapper();
        queryWrapper.in("name",Arrays.asList(split));
        List<Region> regions = regionDao.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(regions)){
            ErrorSpace errorSpace = new ErrorSpace();
            errorSpace.setReason("所在地错误");
            errorSpace.setObj(areaExcelDTO);
            errorSpaceList.add(errorSpace);
            return;
        }
        Map<String,Region> map = new HashMap<>();
        Map<String,Region> mapPid = new HashMap<>();
        for(Region vo:regions){
            map.put(vo.getName(),vo);
            mapPid.put(vo.getName()+vo.getPid(),vo);
        }
        List<String> regionNew = new ArrayList<>();
        String parentId = "";
        for (int i = 0; i < split.length; i++) {
            if(i==0){
                if(map.get(split[0])!= null){
                    parentId=map.get(split[0]).getId()+"";
                    regionNew.add(map.get(split[i]).getId()+"");
                }else{
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("所在地不存在");
                    errorSpace.setObj(areaExcelDTO);
                    errorSpaceList.add(errorSpace);
                    return;
                }
            }else{
                if(mapPid.get(split[i]+parentId)!= null){
                    String id = mapPid.get(split[i]+parentId).getId()+"";
                    parentId = id;
                    regionNew.add(id);
                }else{
                    ErrorSpace errorSpace = new ErrorSpace();
                    errorSpace.setReason("所在地层级错误");
                    errorSpace.setObj(areaExcelDTO);
                    errorSpaceList.add(errorSpace);
                    return;
                }
            }
        }
        JSONObject jsonObject = JSONObject.parseObject(areaExcelDTO.getExpand());
        for (int i = 0; i < regionNew.size(); i++) {
            if(i==0){
                areaExcelDTO.setProvinceId(Integer.parseInt(regionNew.get(i)));
                jsonObject.put("provinceId",Integer.parseInt(regionNew.get(i)));
            }
            if(i==1){
                areaExcelDTO.setCityId(Integer.parseInt(regionNew.get(i)));
                jsonObject.put("cityId",Integer.parseInt(regionNew.get(i)));
            }
            if(i==2){
                areaExcelDTO.setDistrictId(Integer.parseInt(regionNew.get(i)));
                jsonObject.put("districtId",Integer.parseInt(regionNew.get(i)));
            }
        }
        areaExcelDTO.setExpand(jsonObject.toString());
    }
}
